home *** CD-ROM | disk | FTP | other *** search
/ Programmer Power Tools / Programmer Power Tools.iso / progjrn / pj_vga.arc / VGA61-L1.ASM < prev    next >
Assembly Source File  |  1987-12-28  |  7KB  |  297 lines

  1. ; Program to illustrate operation of write mode 3 of the VGA.
  2. ;  Draws 8x8 characters at arbitrary locations without disturbing
  3. ;  the background, using VGA's 8x8 ROM font.  Designed
  4. ;  for use with modes 0Dh, 0Eh, 0Fh, 10h, and 12h.
  5. ; Runs only on VGAs (in Models 50 & up and IBM Display Adapter
  6. ;  and 100% compatibles).
  7. ; Assembled with MASM 4.0, linked with LINK 3.51.
  8. ; By Michael Abrash, 9/1/87.
  9. ; Page 20, Volume 6.1 Programmer's Journal
  10. ;
  11. stack    segment    para stack 'STACK'
  12.     db    512 dup(?)
  13. stack    ends
  14. ;
  15. VGA_VIDEO_SEGMENT    equ    0a000h    ;VGA display memory segment
  16. SCREEN_WIDTH_IN_BYTES    equ    044ah    ;offset of BIOS variable
  17. FONT_CHARACTER_SIZE    equ    8    ;# bytes in each font char
  18. ;
  19. ; VGA register equates.
  20. ;
  21. SC_INDEX    equ    3c4h    ;SC index register
  22. SC_MAP_MASK    equ    2    ;SC map mask register index
  23. GC_INDEX    equ    3ceh    ;GC index register
  24. GC_SET_RESET    equ    0    ;GC set/reset register index
  25. GC_ENABLE_SET_RESET equ    1    ;GC enable set/reset register index
  26. GC_ROTATE    equ    3    ;GC data rotate/logical function
  27.                 ; register index
  28. GC_MODE        equ    5    ;GC Mode register
  29. GC_BIT_MASK    equ    8    ;GC bit mask register index
  30. ;
  31. dseg    segment    para common 'DATA'
  32. TEST_TEXT_ROW    equ    69    ;row to display test text at
  33. TEST_TEXT_COL    equ    17    ;column to display test text at
  34. TEST_TEXT_WIDTH    equ    8    ;width of a character in pixels
  35. TestString    label    byte
  36.     db    'Hello, world!',0    ;test string to print.
  37. FontPointer    dd    ?        ;font offset
  38. dseg    ends
  39. ;
  40. cseg    segment    para public 'CODE'
  41.     assume    cs:cseg, ds:dseg
  42. start    proc    near
  43.     mov    ax,dseg
  44.     mov    ds,ax
  45. ;
  46. ; Select 640x480 graphics mode.
  47. ;
  48.     mov    ax,012h
  49.     int    10h
  50. ;
  51. ; Set the screen to all blue, using the readability of VGA registers
  52. ; to preserve reserved bits.
  53. ;
  54.     mov    dx,GC_INDEX
  55.     mov    al,GC_SET_RESET
  56.     out    dx,al
  57.     inc    dx
  58.     in    al,dx
  59.     and    al,0f0h
  60.     or    al,1        ;blue plane only set, others reset
  61.     out    dx,al
  62.     dec    dx
  63.     mov    al,GC_ENABLE_SET_RESET
  64.     out    dx,al
  65.     inc    dx
  66.     in    al,dx
  67.     and    al,0f0h
  68.     or    al,0fh        ;enable set/reset for all planes
  69.     out    dx,al
  70.     mov    dx,VGA_VIDEO_SEGMENT
  71.     mov    es,dx        ;point to display memory
  72.     mov    di,0
  73.     mov    cx,8000h     ;fill all 32k words
  74.     mov    ax,0ffffh    ;because of set/reset, the value
  75.                 ; written actually doesn't matter
  76.     rep stosw        ;fill with blue
  77. ;
  78. ; Set driver to use the 8x8 font.
  79. ;
  80.     mov    ah,11h    ;VGA BIOS character generator function,
  81.     mov    al,30h    ; return info subfunction
  82.     mov    bh,3    ;get 8x8 font pointer
  83.     int    10h
  84.     call    SelectFont
  85. ;
  86. ; Print the test string, cycling through colors.
  87. ;
  88.     mov    si,offset TestString
  89.     mov    bx,TEST_TEXT_ROW
  90.     mov    cx,TEST_TEXT_COL
  91.     mov    ah,0        ;start with color 0
  92. StringOutLoop:
  93.     lodsb
  94.     and    al,al
  95.     jz    StringOutDone
  96.     push    ax        ;preserve color
  97.     call    DrawChar
  98.     pop    ax        ;restore color
  99.     inc    ah        ;next color
  100.     and    ah,0fh        ;colors range from 0 to 15
  101.     add    cx,TEST_TEXT_WIDTH
  102.     jmp    StringOutLoop
  103. StringOutDone:
  104. ;
  105. ; Wait for a key, then set to text mode & end.
  106. ;
  107.     mov    ah,1
  108.     int    21h    ;wait for a key
  109.     mov    ax,3
  110.     int    10h    ;restore text mode
  111. ;
  112. ; Exit to DOS.
  113. ;
  114.     mov    ah,4ch
  115.     int    21h
  116. Start    endp
  117. ;
  118. ; Subroutine to draw a text character in a linear graphics mode
  119. ;  (0Dh, 0Eh, 0Fh, 010h, 012h). Background around the pixels that
  120. ;  make up the character is preserved.
  121. ; Font used should be pointed to by FontPointer.
  122. ;
  123. ; Input:
  124. ;  AL = character to draw
  125. ;  AH = color to draw character in (0-15)
  126. ;  BX = row to draw text character at
  127. ;  CX = column to draw text character at
  128. ;
  129. ;  Forces ALU function to "move".
  130. ;  Forces write mode 3.
  131. ;
  132. DrawChar    proc    near
  133.     push    ax
  134.     push    bx
  135.     push    cx
  136.     push    dx
  137.     push    si
  138.     push    di
  139.     push    bp
  140.     push    ds
  141.  
  142.     push    ax    ;preserve character to draw in AL
  143. ;
  144. ; Set up set/reset to produce character color, using the readability
  145. ; of VGA register to preserve the setting of reserved bits 7-4.
  146. ;
  147.     mov    dx,GC_INDEX
  148.     mov    al,GC_SET_RESET
  149.     out    dx,al
  150.     inc    dx
  151.     in    al,dx
  152.     and    al,0f0h
  153.     and    ah,0fh
  154.     or    al,ah
  155.     out    dx,al
  156. ;
  157. ; Select write mode 3, using the readability of VGA registers
  158. ; to leave bits other than the write mode bits unchanged.
  159. ;
  160.     mov    dx,GC_INDEX
  161.     mov    al,GC_MODE
  162.     out    dx,al
  163.     inc    dx
  164.     in    al,dx
  165.     or    al,3
  166.     out    dx,al
  167. ;
  168. ; Set DS:SI to point to font and ES to point to display memory.
  169. ;
  170.     lds    si,[FontPointer]    ;point to font
  171.     mov    dx,VGA_VIDEO_SEGMENT
  172.     mov    es,dx            ;point to display memory
  173. ;
  174. ; Calculate screen address of byte character starts in.
  175. ;
  176.     pop    ax    ;get back character to draw in AL
  177.  
  178.     push    ds    ;point to BIOS data segment
  179.     sub    dx,dx
  180.     mov    ds,dx
  181.     xchg    ax,bx
  182.     mov    di,ds:[SCREEN_WIDTH_IN_BYTES]    ;retrieve BIOS
  183.                         ; screen width
  184.     pop    ds
  185.     mul    di    ;calculate offset of start of row
  186.     push    di    ;set aside screen width
  187.     mov    di,cx    ;set aside the column
  188.     and    cl,0111b ;keep only the column in-byte address
  189.     shr    di,1
  190.     shr    di,1
  191.     shr    di,1    ;divide column by 8 to make a byte address
  192.     add    di,ax    ;and point to byte
  193. ;
  194. ; Calculate font address of character.
  195. ;
  196.     sub    bh,bh
  197.     shl    bx,1    ;assumes 8 bytes per character; use
  198.     shl    bx,1    ; a multiply otherwise
  199.     shl    bx,1    ;offset in font of character
  200.     add    si,bx    ;offset in font segment of character
  201. ;
  202. ; Set up the GC rotation. In write mode 3, this is the rotation
  203. ; of CPU data before it is ANDed with the Bit Mask register to
  204. ; form the bit mask. Force the ALU function to "move". Uses the
  205. ; readability of VGA registers to leave reserved bits unchanged.
  206. ;
  207.     mov    dx,GC_INDEX
  208.     mov    al,GC_ROTATE
  209.     out    dx,al
  210.     inc    dx
  211.     in    al,dx
  212.     and    al,0e0h
  213.     or    al,cl
  214.     out    dx,al
  215. ;
  216. ; Set up BH as bit mask for left half, BL as rotation for right half.
  217. ;
  218.     mov    bx,0ffffh
  219.     shr    bh,cl
  220.     neg    cl
  221.     add    cl,8
  222.     shl    bl,cl
  223. ;
  224. ; Draw the character, left half first, then right half in the
  225. ; succeeding byte, using the data rotation to position the character
  226. ; across the byte boundary and then using write mode 3 to combine the
  227. ; character data with the bit mask to allow the set/reset value (the
  228. ; character color) through only for the proper portion (where the
  229. ; font bits for the character are 1) of the character for each byte.
  230. ; Wherever the font bits for the character are 0, the background
  231. ; color is preserved.
  232. ; Does not check for case where character is byte-aligned and
  233. ; no rotation and only one write is required.
  234. ;
  235.     mov    bp,FONT_CHARACTER_SIZE
  236.     mov    dx,GC_INDEX
  237.     pop    cx    ;get back screen width
  238.     dec    cx
  239.     dec    cx    ; -2 because do two bytes for each char
  240. CharacterLoop:
  241. ;
  242. ; Set the bit mask for the left half of the character.
  243. ;
  244.     mov    al,GC_BIT_MASK
  245.     mov    ah,bh
  246.     out    dx,ax
  247. ;
  248. ; Get the next character byte & write it to display memory.
  249. ; (Left half of character.)
  250. ;
  251.     mov    al,[si]        ;get character byte
  252.     mov    ah,es:[di]    ;load latches
  253.     stosb            ;write character byte
  254. ;
  255. ; Set the bit mask for the right half of the character.
  256. ;
  257.     mov    al,GC_BIT_MASK
  258.     mov    ah,bl
  259.     out    dx,ax
  260. ;
  261. ; Get the character byte again & write it to display memory.
  262. ; (Right half of character.)
  263. ;
  264.     lodsb            ;get character byte
  265.     mov    ah,es:[di]    ;load latches
  266.     stosb            ;write character byte
  267. ;
  268. ; Point to next line of character in display memory.
  269. ;
  270.     add    di,cx
  271. ;
  272.     dec    bp
  273.     jnz    CharacterLoop
  274. ;
  275.     pop    ds
  276.     pop    bp
  277.     pop    di
  278.     pop    si
  279.     pop    dx
  280.     pop    cx
  281.     pop    bx
  282.     pop    ax
  283.     ret
  284. DrawChar    endp
  285. ;
  286. ; Set the pointer to the font to draw from to ES:BP.
  287. ;
  288. SelectFont    proc    near
  289.     mov    word ptr [FontPointer],bp    ;save pointer
  290.     mov    word ptr [FontPointer+2],es
  291.     ret
  292. SelectFont    endp
  293. ;  
  294. cseg    ends
  295.     end    start
  296.  
  297.